package controller.backstage;

import com.alibaba.druid.util.StringUtils;
import com.google.gson.*;
import model.Result;
import model.bo.OrderQueryBO;
import model.InnerResult;
import service.OrderService;
import service.impl.OrderServiceImpl;
import utils.HttpUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.time.format.DateTimeFormatter;
import java.util.function.Function;

import static model.InnerResult.Status.FULFILLED;

@WebServlet("/api/admin/order/*")
public class OrderServlet extends HttpServlet {
    private OrderService orderService = new OrderServiceImpl();

    private final String URI_PREFIX = "/api/admin/order/";
    private final Gson GSON = new GsonBuilder()
            .registerTypeAdapter(Timestamp.class, new TimestampSerializer())
            .create();

    private static class TimestampSerializer implements JsonSerializer<Timestamp> {
        final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        @Override
        public JsonElement serialize(Timestamp timestamp, Type type, JsonSerializationContext jsonSerializationContext) {
            return new JsonPrimitive(timestamp.toLocalDateTime().format(dtf));
        }
    }

    private final Function<InnerResult, Result> FILLER = dto -> {
        if (dto.getStatus() == FULFILLED) {
            return Result.fulfill(dto.getObject());
        } else {
            return Result.reject(dto.getObject().toString());
        }
    };

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        String action = req.getRequestURI().replace(URI_PREFIX, "");
        try {
            switch (action) {
                case "order":
                    order(req, resp);
                    break;
                case "deleteOrder":
                    deleteOrder(req, resp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void deleteOrder(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String id = req.getParameter("id");
        if (!StringUtils.isNumber(id) || Integer.parseInt(id) < 1) {
            resp.getWriter().print(GSON.toJson(Result.reject("非法参数")));
            return;
        }
        InnerResult dto = orderService.deleteOrder(id);
        resp.getWriter().print(GSON.toJson(FILLER.apply(dto)));
    }

    private void order(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String id = req.getParameter("id");
        if (!StringUtils.isNumber(id) || Integer.parseInt(id) < 1) {
            resp.getWriter().print(GSON.toJson(Result.reject("非法参数")));
            return;
        }
        InnerResult dto = orderService.order(id);
        resp.getWriter().print(GSON.toJson(FILLER.apply(dto)));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        String action = req.getRequestURI().replace(URI_PREFIX, "");
        try {
            switch (action) {
                case "ordersByPage":
                    ordersByPage(req, resp);
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void ordersByPage(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String requestBody = HttpUtils.getRequestBody(req);
        OrderQueryBO bo = GSON.fromJson(requestBody, OrderQueryBO.class);
        InnerResult dto = orderService.ordersByPage(bo);
        resp.getWriter().print(GSON.toJson(FILLER.apply(dto)));
    }
}
